#include "blockq.h"

typedef struct{
    //线程池中线程的id，因为线程的操作都是通过线程id进行操作的
    pthread_t* pthread;
    int num;    //线程的数量
    BlockQ* q;  //一个阻塞队列

}Threadpool;

// 线程池的创建 + 初始化
Threadpool* Threadpool_create(int n)
{
    //开辟空间
    Threadpool* pool = (Threadpool*) malloc(sizeof(Threadpool));
    //开存在线程id的数组空间
    pool->pthread = (pthread_t*) malloc(n * sizeof(pthread_t));
    pool->num = n;
    pool->q = blockq_create();
    return pool;
}

void Thread_destory(Threadpool* pool)
{
    block_destory(pool->q);
    free(pool->pthread);
    free(pool);
}

void* start_routine(void* args)
{
    Threadpool* pool = (Threadpool*) args;

    pthread_t tid = pthread_self();
    for(;;)
    {
        int task_id = block_pop(pool->q);
        if(task_id == -1)
        {
            printf("0x%lx : task %d done\n", tid, task_id);
            pthread_exit(NULL);
        }
        printf("0x%lx : execute task %d\n", tid, task_id);
        sleep(1);
        printf("0x%lx : task %d done\n", tid, task_id);
    }
    return NULL;
}

int main()
{
    Threadpool* pool = Threadpool_create(8);
    //创建线程
    for(int i = 0; i < pool->num; i++)
    {
        pthread_create(pool->pthread + i, NULL, start_routine, pool);
    }
    //模拟向阻塞队列中添加任务
    for(int i = 1; i <= 100; i++)
    {
        block_push(pool->q, i);
    }

    sleep(10);
    
    //退出
    //1. 强制退出，发送取消请求
    // for(int i = 0; i < pool->num; i++)
    // {
    //     pthread_cancel(pool->pthread[i]);
    // }
    //2.发送特殊的任务
    for(int i = 0; i < pool->num; i++)
    {
        block_push(pool->q, -1);
    }
    //等待 有序退出
    for(int i =0; i < pool->num; i++)
    {
        pthread_join(*(pool->pthread+i), NULL);
    }

    Thread_destory(pool);
    return 0;
}